﻿using EntityFramework.Data.Core;
using Framework.Common;
using Framework.Common.Paged;
using IRepositories.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using YouTravel.DomainModels;
using YouTravel.Framework.Const;
using YouTravel.Framework.Enums;
using YouTravel.QueryModels;
using YouTravel.ViewModels;
using System.Data.Entity;
using Framework.Common.Exceptions;
using YouTravel.Framework.ResourceMessage;
namespace YouTravel.DomainService
{
	public class BranchService : IBranchService
	{
	    readonly IEFRepository<Branch> _baranchRepository;
	    readonly IEFRepository<Deduction> _deductionRepository;
	    readonly IEFRepository<InvoiceSubject> _invoicesubjectRepository;
	    readonly IEFRepository<User> _userRepository;
	    readonly IUnitOfWork _db;
		public BranchService(IUnitOfWork db, IEFRepository<Branch> baranchRepository,
			IEFRepository<Deduction> deductionRepository, IEFRepository<InvoiceSubject> invoicesubjectRepository, IEFRepository<User> userRepository)
		{
			this._db = db;
			this._baranchRepository = baranchRepository;
			this._deductionRepository = deductionRepository;
			this._invoicesubjectRepository = invoicesubjectRepository;
			this._userRepository = userRepository;
			this._userRepository.SetDbContext(this._db);
			this._baranchRepository.SetDbContext(this._db);
			this._deductionRepository.SetDbContext(this._db);
			this._invoicesubjectRepository.SetDbContext(this._db);
		}


		/// <summary>
		/// 机构列表页面 Pwp 2015-09-16
		/// </summary>
		/// <param name="queryCond"></param>
		/// <returns></returns>
		public CustomPagedList<BranchListViewModel> GetList(PagedParam<BranchQuery> queryCond)
		{
            return _baranchRepository.GetModel()
                .GetPagedList(queryCond.PageDto.PageNo,
				queryCond.PageDto.PageSize, BuildQueryCondition(queryCond.QueryDto),
				queryCond.SortField).ToCustomPagedList<Branch, BranchListViewModel>((u) =>
                {
					var s = u.MapNew<Branch, BranchListViewModel>();
					//s.Name = u.Name
                    return s;
                });
		}

		/// <summary>
		/// 创建机构 Pwp 2015-09-17
		/// </summary>
		/// <param name="branchview"></param>
		/// <returns></returns>
		public void AddBranch(BranchViewModel branchview)
		{
			//bool isBranchStatus = Convert.ToBoolean((int)BranchStatus.Normal);
			int iCount = _baranchRepository.GetModelTracking().Where(o => o.Name == branchview.Name).Count();
			if (iCount > 0)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemBeenHade, "机构名称"));
			//机构类填充
			Branch mBranch = new Branch();
			mBranch.Name = branchview.Name;
			mBranch.Status = Convert.ToBoolean((int)BranchStatus.Normal);
			//mBranch.Type = (BranchType)_branchview.Type;
			mBranch.Type = BranchType.Branch;
			mBranch.GrossMargin = branchview.GrossMargin;
			mBranch.CounterFeeRate = branchview.CounterFeeRate;
			mBranch.ArrearsTotal = branchview.ArrearsTotal;
			mBranch.OweTicketsDay = branchview.OweTicketsDay;
			mBranch.CreaterId = branchview.OperatorID;
			mBranch.CreateTime = branchview.OptionTime;
			mBranch.UpdaterId = branchview.OperatorID;
			mBranch.UpdaterName = branchview.OperatorName;
			mBranch.UpdateTime = branchview.OptionTime;

			TransactionScopeNoMsdtc.UsingTransactionNoMsdtc(_db, () =>
			{
				_baranchRepository.Insert(mBranch);
				List<Deduction> lstDeduction = new List<Deduction>();
				Deduction mDeduction = null;

				////默认扣款类型
				//string[] arrDeduction = BusinessConst._DEDUCTIONNAME;
				//foreach (string strDeductionTemp in arrDeduction)
				//{
				//	mDeduction = new Deduction();
				//	mDeduction.BranchId = mBranch.ID;
				//	mDeduction.Name = strDeductionTemp;
				//	mDeduction.Status = Convert.ToBoolean((int)DeductionStatus.Normal); 
				//	mDeduction.CreaterId = _branchview.OperatorID;
				//	mDeduction.CreateTime = _branchview.OptionTime;
				//	mDeduction.UpdaterId = _branchview.OperatorID;
				//	mDeduction.UpdateTime = _branchview.OptionTime;
				//	lstDeduction.Add(mDeduction);
				//}

				//#region 传json字符串处理方式
				////选择的扣款类型
				//foreach (BranchDeduction Temp in _branchview.LstDeduction)
				//{
				//	mDeduction = new Deduction();
				//	mDeduction.BranchId = mBranch.ID;
				//	mDeduction.Name = Temp.Name;
				//	mDeduction.Status = bool.Parse(DeductionStatus.Normal.ToString());
				//	mDeduction.CreaterId = _branchview.OperatorID;
				//	mDeduction.CreateTime = _branchview.OptionTime;
				//	mDeduction.UpdaterId = _branchview.OperatorID;
				//	mDeduction.UpdateTime = _branchview.OptionTime;
				//	lstDeduction.Add(mDeduction);
				//}
				//deductionRepository.Insert(lstDeduction);
				////选择的开出发票科目
				//List<InvoiceSubject> lstInvoiceSubject = new List<InvoiceSubject>();
				//InvoiceSubject mInvoiceSubject = null;
				//foreach (BranchInvoice Temp in _branchview.LstInvoice)
				//{
				//	mInvoiceSubject = new InvoiceSubject();
				//	mInvoiceSubject.BranchId = mBranch.ID;
				//	mInvoiceSubject.InvoiceSubjectName = Temp.Name;
				//	mInvoiceSubject.Status = bool.Parse(InvoiceSubjectStatus.Normal.ToString());
				//	mInvoiceSubject.Type = bool.Parse(InvoiceSubjectType.ExpenditureInvoice.ToString());
				//	mInvoiceSubject.CreaterId = _branchview.OperatorID;
				//	mInvoiceSubject.CreateTime = _branchview.OptionTime;
				//	mInvoiceSubject.UpdaterId = _branchview.OperatorID;
				//	mInvoiceSubject.UpdateTime = _branchview.OptionTime;
				//	lstInvoiceSubject.Add(mInvoiceSubject);
				//}
				////添加的收回发票科目
				//foreach (BranchCollectInvoice Temp in _branchview.LstCollectInvoice)
				//{
				//	mInvoiceSubject = new InvoiceSubject();
				//	mInvoiceSubject.BranchId = mBranch.ID;
				//	mInvoiceSubject.InvoiceSubjectName = Temp.Name;
				//	mInvoiceSubject.Status = bool.Parse(InvoiceSubjectStatus.Normal.ToString());
				//	mInvoiceSubject.Type = bool.Parse(InvoiceSubjectType.BackInvoice.ToString());
				//	mInvoiceSubject.CreaterId = _branchview.OperatorID;
				//	mInvoiceSubject.CreateTime = _branchview.OptionTime;
				//	mInvoiceSubject.UpdaterId = _branchview.OperatorID;
				//	mInvoiceSubject.UpdateTime = _branchview.OptionTime;
				//	lstInvoiceSubject.Add(mInvoiceSubject);
				//}
				//invoicesubjectRepository.Insert(lstInvoiceSubject);
				//#endregion

				//选择的扣款类型
				foreach (string temp in branchview.Deduction.Split('-'))
				{
					mDeduction = new Deduction();
					mDeduction.BranchId = mBranch.ID;
					mDeduction.Name = temp;
					mDeduction.Status = Convert.ToBoolean((int)DeductionStatus.Normal); 
					mDeduction.CreaterId = branchview.OperatorID;
					mDeduction.CreateTime = branchview.OptionTime;
					mDeduction.UpdaterId = branchview.OperatorID;
					mDeduction.UpdateTime = branchview.OptionTime;
					lstDeduction.Add(mDeduction);
				}
				_deductionRepository.Insert(lstDeduction);
				//选择的开出发票科目
				List<InvoiceSubject> lstInvoiceSubject = new List<InvoiceSubject>();
				InvoiceSubject mInvoiceSubject = null;
				foreach (string temp in branchview.Invoice.Split('-'))
				{
					mInvoiceSubject = new InvoiceSubject();
					mInvoiceSubject.BranchId = mBranch.ID;
					mInvoiceSubject.InvoiceSubjectName = temp;
					mInvoiceSubject.Status = Convert.ToBoolean((int)InvoiceSubjectStatus.Normal);
					mInvoiceSubject.Type = Convert.ToBoolean((int)InvoiceSubjectType.ExpenditureInvoice);
					mInvoiceSubject.CreaterId = branchview.OperatorID;
					mInvoiceSubject.CreateTime = branchview.OptionTime;
					mInvoiceSubject.UpdaterId = branchview.OperatorID;
					mInvoiceSubject.UpdateTime = branchview.OptionTime;
					lstInvoiceSubject.Add(mInvoiceSubject);
				}
				//添加的收回发票科目
				foreach (string temp in branchview.CollectInvoice.Split('-'))
				{
					mInvoiceSubject = new InvoiceSubject();
					mInvoiceSubject.BranchId = mBranch.ID;
					mInvoiceSubject.InvoiceSubjectName = temp;
					mInvoiceSubject.Status = Convert.ToBoolean((int)InvoiceSubjectStatus.Normal);
					mInvoiceSubject.Type = Convert.ToBoolean((int)InvoiceSubjectType.BackInvoice); 
					mInvoiceSubject.CreaterId = branchview.OperatorID;
					mInvoiceSubject.CreateTime = branchview.OptionTime;
					mInvoiceSubject.UpdaterId = branchview.OperatorID;
					mInvoiceSubject.UpdateTime = branchview.OptionTime;
					lstInvoiceSubject.Add(mInvoiceSubject);
				}
				_invoicesubjectRepository.Insert(lstInvoiceSubject);
			});
		}

		/// <summary>
		/// 获取机构信息 Pwp 2015-09-18
		/// </summary>
		/// <param name="branchid"></param>
		/// <returns></returns>
		public BranchViewModel DetailBranch(int branchid)
		{
			//查询需要的状态
			//bool DeductionStatusNormal = Convert.ToBoolean((int)DeductionStatus.Normal);
			bool branchInvoiceTypeBackInvoice = Convert.ToBoolean((int)InvoiceSubjectType.BackInvoice);
			bool branchInvoiceTypeExpenditureInvoice = Convert.ToBoolean((int)InvoiceSubjectType.ExpenditureInvoice);
			//bool InvoiceSubjectStatusNormal = Convert.ToBoolean((int)InvoiceSubjectStatus.Normal);

			//获取机构信息
			Branch mBranch = (from p in _baranchRepository.GetModel()
							  where p.ID == branchid
							  select p).FirstOrDefault();

			//获取扣款类型
			List<BranchDeduction> lstDeduction = (from p in _deductionRepository.GetModel()
												  where p.BranchId == branchid  && !BusinessConst._DEDUCTIONNAME.Contains(p.Name) 
												  select new BranchDeduction
												  {
													  ID = p.ID,
													  Name = p.Name,
													  Status = p.Status
												  }).ToList();
			//获取发票科目
			List<InvoiceSubject> lstInvoiceSubject = (from p in _invoicesubjectRepository.GetModel()
													  where p.BranchId == branchid
													  select p).ToList();
			//获取发票科目(出票)
			List<BranchInvoice> lstBranchInvoice = (from p in lstInvoiceSubject
													where p.Type == branchInvoiceTypeExpenditureInvoice 
													select new BranchInvoice
													{
														ID = p.ID,
														Name = p.InvoiceSubjectName,
														Status = p.Status
													}).ToList();
			//获取发票科目(收票)
			List<BranchCollectInvoice> lstBranchCollectInvoice = (from p in lstInvoiceSubject
																  where p.Type == branchInvoiceTypeBackInvoice 
																  select new BranchCollectInvoice
														   {
															   ID = p.ID,
															   Name = p.InvoiceSubjectName,
															   Status = p.Status
														   }).ToList();

			BranchViewModel mBranchViewModel = new BranchViewModel();
			mBranchViewModel.ID = mBranch.ID;
			mBranchViewModel.Name = mBranch.Name;
			mBranchViewModel.Type = (int)mBranch.Type;
			mBranchViewModel.GrossMargin = mBranch.GrossMargin;
			mBranchViewModel.CounterFeeRate = mBranch.CounterFeeRate;
			mBranchViewModel.ArrearsTotal = mBranch.ArrearsTotal;
			mBranchViewModel.OweTicketsDay = mBranch.OweTicketsDay;
			mBranchViewModel.LstDeduction = lstDeduction;
			mBranchViewModel.LstInvoice = lstBranchInvoice;
			mBranchViewModel.LstCollectInvoice = lstBranchCollectInvoice;
			return mBranchViewModel;
		}

		/// <summary>
		/// 编辑机构基础信息 Pwp 2015-09-18
		/// </summary>
		/// <param name="branchmodel"></param>
		/// <returns></returns>
		public void EditBranch(BranchViewModel branchmodel)
		{
			//baranchRepository.Update(x => x.ID == _branchmodel.ID, u => new Branch
			//{
			//	UpdaterId = _branchmodel.OperatorID,
			//	UpdaterName = _branchmodel.OperatorName,
			//	UpdateTime = _branchmodel.OptionTime,
			//	GrossMargin = _branchmodel.GrossMargin,
			//	CounterFeeRate = _branchmodel.CounterFeeRate,
			//	ArrearsTotal = _branchmodel.ArrearsTotal,
			//	OweTicketsDay = _branchmodel.OweTicketsDay
			//});

			#region 根据类型条件进行更新
			switch (branchmodel.Type)
			{
				case 1:
					_baranchRepository.Update(x => x.ID == branchmodel.ID, u => new Branch
					{
						UpdaterId = branchmodel.OperatorID,
						UpdaterName = branchmodel.OperatorName,
						UpdateTime = branchmodel.OptionTime,
						GrossMargin = branchmodel.GrossMargin
					});
					break;
				case 2:
					_baranchRepository.Update(x => x.ID == branchmodel.ID, u => new Branch
					{
						UpdaterId = branchmodel.OperatorID,
						UpdaterName = branchmodel.OperatorName,
						UpdateTime = branchmodel.OptionTime,
						CounterFeeRate = branchmodel.CounterFeeRate
					});
					break;
				case 3:
					_baranchRepository.Update(x => x.ID == branchmodel.ID, u => new Branch
					{
						UpdaterId = branchmodel.OperatorID,
						UpdaterName = branchmodel.OperatorName,
						UpdateTime = branchmodel.OptionTime,
						ArrearsTotal = branchmodel.ArrearsTotal
					});
					break;
				case 4:
					_baranchRepository.Update(x => x.ID == branchmodel.ID, u => new Branch
					{
						UpdaterId = branchmodel.OperatorID,
						UpdaterName = branchmodel.OperatorName,
						UpdateTime = branchmodel.OptionTime,
						OweTicketsDay = branchmodel.OweTicketsDay
					});
					break;
				case 0:
				default:
					_baranchRepository.Update(x => x.ID == branchmodel.ID, u => new Branch
					{
						UpdaterId = branchmodel.OperatorID,
						UpdaterName = branchmodel.OperatorName,
						UpdateTime = branchmodel.OptionTime,
						GrossMargin = branchmodel.GrossMargin,
						CounterFeeRate = branchmodel.CounterFeeRate,
						ArrearsTotal = branchmodel.ArrearsTotal,
						OweTicketsDay = branchmodel.OweTicketsDay
					});
					break;
			}
			#endregion
		}

		/// <summary>
		/// 冻结/解冻机构 Pwp 2015-09-18
		/// </summary>
		/// <param name="branchmodel"></param>
		/// <returns></returns>
		public void FrozenBranch(Branch branchmodel)
		{
			_baranchRepository.Update(x => x.ID == branchmodel.ID, u => new Branch
			{
				Status = branchmodel.Status,
				UpdaterId = branchmodel.UpdaterId,
				UpdaterName = branchmodel.UpdaterName,
				UpdateTime = branchmodel.UpdateTime
			});
			var lstUser = _userRepository.GetModelTracking().Where(o => o.BranchId == branchmodel.ID);
			foreach (var item in lstUser)
			{
				var tmp = RedisHelp.GetLoginUserCache(item.ID);
				if (tmp != null)
				{
					tmp.Branch.Status = branchmodel.Status;
					RedisHelp.RefreshLoginUserCache(tmp);
				}
			}
		}

		/// <summary>
		/// 创建扣款类型 Pwp 2015-09-18
		/// </summary>
		/// <param name="deductionmodel"></param>
		/// <returns></returns>
		public void AddDeduction(Deduction deductionmodel)
		{
			int iCount = _deductionRepository.GetModelTracking().Where(o => o.Name == deductionmodel.Name && o.BranchId == deductionmodel.BranchId).Count();
			if (iCount > 0)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemBeenHade, "扣款类型名称"));
			deductionmodel.Status = Convert.ToBoolean((int)DeductionStatus.Normal);
			_deductionRepository.Insert(deductionmodel);
		}

		/// <summary>
		/// 删除扣款类型 Pwp 2015-09-18
		/// </summary>
		/// <param name="deductionmodel"></param>
		/// <returns></returns>
		public void DelDeduction(Deduction deductionmodel)
		{
			_deductionRepository.Update(x => x.ID == deductionmodel.ID, u => new Deduction
			{
				Status = deductionmodel.Status,
				UpdaterId = deductionmodel.UpdaterId,
				UpdateTime = deductionmodel.UpdateTime
			});
		}

		/// <summary>
		/// 创建发票科目 Pwp 2015-09-18
		/// </summary>
		/// <param name="_deductionmodel"></param>
		/// <returns></returns>
		public void AddInvoiceSubject(InvoiceSubject invoicesubjectmodel)
		{
			int iCount = _invoicesubjectRepository.GetModelTracking().Where(o => o.InvoiceSubjectName == invoicesubjectmodel.InvoiceSubjectName 
				&& o.BranchId == invoicesubjectmodel.BranchId
				&& o.Type == invoicesubjectmodel.Type).Count();
			if (iCount > 0)
				throw new BusinessException(string.Format(BusinessResourceMessage.ItemBeenHade, "发票科目名称"));

			invoicesubjectmodel.Status = Convert.ToBoolean((int)InvoiceSubjectStatus.Normal); 
			_invoicesubjectRepository.Insert(invoicesubjectmodel);
		}

		/// <summary>
		/// 删除发票科目 Pwp 2015-09-18
		/// </summary>
		/// <param name="_deductionmodel"></param>
		/// <returns></returns>
		public void DelInvoiceSubject(InvoiceSubject invoicesubjectmodel)
		{
			_invoicesubjectRepository.Update(x => x.ID == invoicesubjectmodel.ID, u => new InvoiceSubject
			{
				Status = invoicesubjectmodel.Status,
				UpdaterId = invoicesubjectmodel.UpdaterId,
				UpdateTime = invoicesubjectmodel.UpdateTime
			});
		}

		/// <summary>
		/// 查询条件处理
		/// </summary>
		/// <param name="branchQuery"></param>
		/// <returns></returns>
		private Func<IQueryable<Branch>, IQueryable<Branch>> BuildQueryCondition(BranchQuery branchQuery)
		{
			return (query) =>
			{
				if (branchQuery != null)
				{
					if (!string.IsNullOrEmpty(branchQuery.Name))
						query = query.Where(p => p.Name.Contains(branchQuery.Name));
					if (!string.IsNullOrEmpty(branchQuery.Status)) {
						bool isBranchStatus = Convert.ToBoolean(branchQuery.Status);
						query = query.Where(p => p.Status == isBranchStatus);
					}
					if (!string.IsNullOrEmpty(branchQuery.Type)){
						BranchType dtBranchType = (BranchType)(int.Parse(branchQuery.Type));
						query = query.Where(p => p.Type == dtBranchType);
					}
				}
				return query;
			};
		}



	}
}
